#ifndef JPEGPARSE_H
#define JPEGPARSE_H
#include "stdafx.h"
#include <string>

using namespace std;

class freeImage;
typedef unsigned char BYTE;

#define NUM_COLOR 256
#define MIN(x,y) (x)>(y)?(y):(x)
#define MAX(x,y) (x)<(y)?(y):(x)
typedef enum 
  {
    R = 0,
    G = 1,
    B = 2,
    L = 3,
    CHANNEL_MAX
  } channel;

typedef unsigned int uint;


class freeImage
{
 private:
  bool bIsInit;
 public:
  freeImage(void);
  void Init(void);
  void Destroy(void);
  bool IsInit(void);
};

class jpegParser
{
 private:
  static freeImage* singleton;
 public:
  static freeImage* GetSingleton()
    {
      if (!singleton)
	singleton = new freeImage();
      return singleton;
    }
  ~jpegParser(void)
    {
      if (singleton)
	{
	  if (singleton->IsInit())
	    singleton->Destroy();
	  delete singleton;
	  singleton = NULL;
	}
    }
};


class color
{
 public:
  BYTE r, g, b, a;
  color(void) : r(0), g(0), b(0), a(0)
    {
    }
    color(BYTE _r, BYTE _g, BYTE _b, BYTE _a) : r(_r), g(_g), b(_b), a(_a)
      {
      }
} ;

typedef struct
{
  uint mean;
  float variance;
  float error;
} statisticalInfo;

class image
{
 private:
  uint width;
  uint height;
  color* pxs;
  BYTE* red;
  BYTE* green;
  BYTE* blue;
  BYTE* grayscale;
  uint redHist[NUM_COLOR];
  uint greenHist[NUM_COLOR];
  uint blueHist[NUM_COLOR];
  uint illumHist[NUM_COLOR];
  statisticalInfo redInfo;
  statisticalInfo greenInfo;
  statisticalInfo blueInfo;
  statisticalInfo illumInfo;
  void calculateHistogram(BYTE* channel, uint numPixels, uint* histogram, image* mask);
  void calculateStatisticalInfo(BYTE* channel, uint numPixels, statisticalInfo* info, image* mask);
  void calculateError(BYTE* channel, uint numPixels, statisticalInfo* info, image* mask);
  void initialize(void);
  void copyFrom(const image& target);
 public:
  image(void);
  image(const image& im);
  image(uint width, uint height);
  image* operator-(const image& im);
  image& operator=(const image& im);
  uint GetWidth(void) const
  {
    return width;
  }
  uint GetHeight(void) const
  {
    return height;
  }
  color* GetBits(void) const
    {
      return pxs;
    }
  bool ReadFromFile(string filename, bool bMask = false);
  bool SaveToFile(string filename);
  void ReadFromMemory(void);
  void ReadFromBuffer(void* buffer, int numBytesPerElem);
  void draw(void);
  void histogram(image* mask = NULL);
  void dumpHistogram(string filename);
  void statistics(image* mask = NULL);
  void errorTo(image* comparisonImage, image* mask = NULL);
  uint* GetHistogram(channel c);
  uint GetMean(channel c);
  float GetError(channel c);
  float GetVariance(channel c);
  ~image(void);
};
#endif
